package com.inspur.edp.common.expr;

import com.inspur.edp.common.expr.ast.ASTContext;
import com.inspur.edp.common.expr.expresses.array.ArrayAccessDSL;
import com.inspur.edp.common.expr.expresses.array.ArrayAccessExpr;
import com.inspur.edp.common.expr.expresses.calculate.CalculateDSL;
import com.inspur.edp.common.expr.expresses.calculate.CalculateExpr;
import com.inspur.edp.common.expr.expresses.compare.CompareDSL;
import com.inspur.edp.common.expr.expresses.compare.CompareExpr;
import com.inspur.edp.common.expr.expresses.constant.*;
import com.inspur.edp.common.expr.expresses.field.FieldAccessDSL;
import com.inspur.edp.common.expr.expresses.field.FieldAccessExpr;
import com.inspur.edp.common.expr.expresses.field.LwFieldAccessDSL;
import com.inspur.edp.common.expr.expresses.field.LwFieldAccessExpr;
import com.inspur.edp.common.expr.expresses.help.HelpValueDSL;
import com.inspur.edp.common.expr.expresses.help.HelpValueExpr;
import com.inspur.edp.common.expr.expresses.logic.LogicExpr;
import com.inspur.edp.common.expr.expresses.logic.LogicExprDSL;
import com.inspur.edp.common.expr.expresses.method.MethodInvokeDSL;
import com.inspur.edp.common.expr.expresses.method.MethodInvokeExpr;
import com.inspur.edp.common.expr.expresses.newexp.NewExpr;
import com.inspur.edp.common.expr.expresses.newexp.NewExprDSL;
import com.inspur.edp.common.expr.expresses.node.NodeVariableDSL;
import com.inspur.edp.common.expr.expresses.node.NodeVariableExpr;
import com.inspur.edp.common.expr.expresses.not.NotExpress;
import com.inspur.edp.common.expr.expresses.not.NotExpressDSL;
import com.inspur.edp.common.expr.expresses.setvalue.AssignValueDSL;
import com.inspur.edp.common.expr.expresses.setvalue.AssignValueExpr;
import com.inspur.edp.common.expr.expresses.setvalue.SetValueDSL;
import com.inspur.edp.common.expr.expresses.setvalue.SetValueExpr;
import com.inspur.edp.common.expr.expresses.variable.VariableDefDSL;
import com.inspur.edp.common.expr.expresses.variable.VariableDefExpr;
import com.inspur.edp.common.expr.expresses.variable.VariableRefDSL;
import com.inspur.edp.common.expr.expresses.variable.VariableRefExpr;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lizhaorui
 * @description TODO
 * @date 2024/12/16 17:24
 */
public class ExpressDSLGeneratorMgr {

    private static ExpressDSLGeneratorMgr instance;

    private Map<String, ExpressDSLGenerator> typeMap = new HashMap<>();

    public static ExpressDSLGeneratorMgr getInstance() {
        if (instance == null) {
            synchronized (ExpressDSLGeneratorMgr.class) {
                if (instance == null) {
                    ExpressDSLGeneratorMgr temp = new ExpressDSLGeneratorMgr();
                    temp.typeMap.put(CalculateExpr.KIND, new CalculateDSL());
                    temp.typeMap.put(CompareExpr.KIND, new CompareDSL());
                    temp.typeMap.put(BoolConstExpr.KIND, new BoolConstDSL());
                    temp.typeMap.put(EnumConstExpr.KIND, new EnumConstDSL());
                    temp.typeMap.put(NumberConstExpr.KIND, new NumberConstDSL());
                    temp.typeMap.put(StaticFieldConstExpr.KIND, new StaticFieldConstDSL());
                    temp.typeMap.put(StringConstExpr.KIND, new StringConstDSL());
                    temp.typeMap.put(StringsConstExpr.KIND, new StringsConstDSL());
                    temp.typeMap.put(LogicExpr.KIND, new LogicExprDSL());
                    temp.typeMap.put(ArrayAccessExpr.KIND, new ArrayAccessDSL());
                    temp.typeMap.put(FieldAccessExpr.KIND, new FieldAccessDSL());
                    temp.typeMap.put(LwFieldAccessExpr.KIND, new LwFieldAccessDSL());
                    temp.typeMap.put(MethodInvokeExpr.KIND, new MethodInvokeDSL());
                    temp.typeMap.put(VariableRefExpr.KIND, new VariableRefDSL());
                    temp.typeMap.put(VariableDefExpr.KIND, new VariableDefDSL());
                    temp.typeMap.put(SetValueExpr.KIND, new SetValueDSL());
                    temp.typeMap.put(AssignValueExpr.KIND, new AssignValueDSL());
                    temp.typeMap.put(NotExpress.KIND, new NotExpressDSL());
                    temp.typeMap.put(HelpValueExpr.KIND, new HelpValueDSL());
                    temp.typeMap.put(NewExpr.KIND, new NewExprDSL());
                    temp.typeMap.put(NodeVariableExpr.KIND, new NodeVariableDSL());
                    instance = temp;
                }
            }
        }
        return instance;
    }

    public static String generateDsl(ASTContext context, Express express) {
        ExpressDSLGenerator dslGen = ExpressDSLGeneratorMgr.getInstance().typeMap.get(express.getKind());
        return dslGen.generate(context, express);
    }

}
